<?php
/**
 * I-Framework Application 定义
 * 
 * 包含该文件后，将把magic_quotes_runtime设为0
 *
 * @author iwind <iwind.iwind@gmail.com>
 * @link http://www.4kiki.net/
 * @version $Id: IApplication.php 323 2008-05-14 05:49:20Z iwind $
 * @package iframework
 */
/**
 * 定义常量
 *
 */
define("IFRAMEWORK_DIRECTORY", dirname(__FILE__));
define("IFRAMEWORK_APC_ENABLED", ini_get("apc.enabled"));

/**
 * 设置选项
 * 
 * @since 0.0.3
 */
set_magic_quotes_runtime(0);


/**
 * 包含文件
 */
require_once IFRAMEWORK_DIRECTORY . "/config/system.conf.php";
require_once IFRAMEWORK_DIRECTORY . "/util/core/native.php";
require_once IFRAMEWORK_DIRECTORY . "/util/core/functions.php";

/**
 * 注册autoload函数
 * 
 * @since 0.2
 */
if (function_exists("spl_autoload_register")) {
	spl_autoload_register("classAutoLoad");
}
else {
	function __autoload($className) {
		classAutoload($className);
	}
}

/**
 * 导入核心类
 */
native::import("IObject");
native::import("IConfig");
native::import("ILogger");
native::import("IExceptionHandler");


/**
 * IApplication - 主应用程序入口.
 * 
 * 所有的controller需继承该类，才能使用实现请求与响应的映射
 *
 * @version $Id: IApplication.php 323 2008-05-14 05:49:20Z iwind $
 * @package iframework
 */
abstract class IApplication extends IObject {
	/**
	 * post,get,command-line输入的数据对象
	 *
	 * @var in
	 */
	protected $in;
	private $action;
	private $controller;
	private static $defaultAction = "index";
	private static $actionPrefix = "app";
	private static $actionKeyword = "action";
	private static $controllerKeyword = "controller";
	const SUCCESS = "success";
	const FAILURE = "failure";
	const ERROR = "error";
	const INPUT = "input";
	const LOGIN = "login";
	protected $config;
	
	
	/**
	 * action的返回值
	 *
	 * @var mixed
	 * @since 0.1.1
	 */
	private $actionReturn;
	
	/**
	 * 过滤器链
	 *
	 * @var IFilterChain
	 * @since 0.0.3
	 */
	private $filterChain;
	
	/**
	 * 参数
	 *
	 * @var array
	 * @since 0.1
	 */
	private $params = array();
	
	/**
	 * 构造器.
	 *
	 */
	public final function __construct() {
		//check config
		if (!defined("IFRAMEWORK_APP_ROOT")) {
			throw new IException("application config file is not loaded");
		}
		
		$this->in = in::getInstance();
		
		if ($this->action == "") {
			$keyword = self::$actionKeyword;
			$requestAction = $this->in->$keyword;
			if ($requestAction == null) {
				$this->action = self::$defaultAction;
			}
			else {
				$this->action = $requestAction;
			}
		}

		$this->config = IConfig::getUserConfig();	
	}
	
	/**
	 * 设置当前请求的action名称
	 *
	 * @param string $action action名称
	 */
	public function setAction($action) {
		$this->action = $action;
	}
	
	/**
	 * 设置action名称的关键字
	 *
	 * @param string $keyword 默认为action
	 */
	public function setActionKeyword($keyword) {
		if ($keyword != null) {
			self::$actionKeyword = $keyword;
		}
		else {
			ILogger::fatal("invalid action keyword '{$keyword}'");
		}
	}
	
	/**
	 * 设置默认执行的action
	 *
	 * @param string $defaultAction 默认执行的action名称，默认为index
	 */
	public function setDefaultAction($defaultAction) {
		if (!preg_match("/^[a-z0-9_]+$/i", $defaultAction)) {
			ILogger::fatal("invalid defaut action '{$defaultAction}'");
		}
		self::$defaultAction = $defaultAction;
	}
	/**
	 * 取得默认执行的action
	 *
	 * @return string
	 */
	public function getDefaultAction() {
		return self::$defaultAction;
	}
	
	/**
	 * 设置action的前缀
	 *
	 * @param string $prefix 前缀字符串，默认为app
	 */
	public function setActionPrefix($prefix) {
		if (!preg_match("/^[a-z0-9_]+$/i", $prefix)) {
			ILogger::fatal("invalid action prefix '{$prefix}'");
		}
		self::$actionPrefix = $prefix;
	}
	
	/**
	 * 执行当前应用
	 *
	 * 从0.1开始，如果action没有返回值，或者返回null，则自动查找相对应的模板文件。
	 * 比如
	 * <code>
	 * class TestController {
	 * 		public function appIndex() {
	 * 		}
	 * }
	 * </code>
	 * 对应一个模板
	 * <pre>
	 * /mint/template
	 *              /test
	 *                 /index.html
	 * </pre>
	 * 那么index.html将会被使用
	 * 
	 * 如果不想使用这种功能，你需要给appIndex一个非null的返回值，通常可以
	 * <code>
	 * class TestController {
	 * 		public function appIndex() {
	 * 			//do business things
	 * 
	 * 			return true;
	 * 		}
	 * }
	 * </code>
	 */
	public function run() {		
		$action = &$this->action;
		
		//默认action
		if ($action == null) {
			$action = self::$defaultAction;
		}
		
		//执行filter
		if ($this->filterChain != null) {
			$this->filterChain->doFilter($this);
		}
		
		//初始化
		if (method_exists($this, "init")) {
			$this->init();
		}	
		
		$className = get_class($this);
		$method = self::$actionPrefix . $action;
		
		if (method_exists($this, $method)) {
			$reflectionClass = new IReflection($className);
			try {
				$this->actionReturn = $reflectionClass->invoke($this, $method);
			} catch (IReflectionTooFewArgumentsException $e) {
				ILogger::fatal("method '$className::{$method}' can't has arguments");
			}
			if ($this->actionReturn instanceof IModelAndView) {
				$this->actionReturn->setInvokingMethod($method);
			}
									
			//invoke view scheme
			if ($this->actionReturn instanceof IViewScheme) {
				//add controller values
				if (!($this->actionReturn instanceof IJSON) && !($this->actionReturn instanceof IJSONResponse) && !($this->actionReturn instanceof IModelAndXml)) {
					$this->actionReturn->put("in", $this->getIn());	
					$this->actionReturn->put("app", $this);		
				}	
				$this->actionReturn->invoke();
			}
			if (is_scalar($this->actionReturn)) {//从配置中读取模板名
				$returnTypes = IConfig::getReturnTypes($this->controller, $this->action);
				if (isset($returnTypes[$this->actionReturn])) {
					$returnType = $returnTypes[$this->actionReturn];
					if (is_scalar($returnType)) {
						$this->display($returnTypes[$this->actionReturn]);
					}
					else if (is_array($returnType) && isset($returnType["controller"]) && isset($returnType["action"])) {
						$this->redirect($returnType["controller"], $returnType["action"]);	
					}
				}
			}
			
			//自动查找模板
			if ($this->actionReturn === null) {
				$tpl = null;
				try {
					$pieces = explode(".", $this->controller);
					$lastIndex = count($pieces) - 1;
					$pieces[$lastIndex] = native::nameToC($pieces[$lastIndex]);
					$tplName = implode("/", $pieces) . "/" . native::nameToC($this->action);
					$tpl = IMint::getFile($tplName);
				} catch(IMintException $e) {
					ILogger::debug($e->getMessage());
				}
				if ($tpl != null && $tpl->exists()) {
					$this->display($tplName);
				}
			}
		}
		else {
			ILogger::fatal("can't find action '{$action}' in '" . $className . "'");
		}
		if (method_exists($this, "destroy")) {
			$this->destroy();
		}
	}
	
	/**
	 * 快速执行，不需要手工实例化对象.
	 * 
	 * <code>
	 * <?php
	 * require "../iframework/IApplication.php";
	 * IApplication::loadConfig("../config/application.conf.php");
	 * IApplication::loadMvcConfig("../config/mvc.conf.php");
	 * 
	 * IApplication::quickRun(array(
	 * 								"actionKeyword"=>"action",
	 * 								"controllerKeyword"=>"module"
	 * 						));
	 * ?>
	 * </code>
	 * 
	 * @param array $config 配置.可以有的选项是：actionKeyword,controllerKeyword
	 */
	public static function quickRun(array $config = null, $controllerName = null, $actionName = null) {
		if ($config == null) {
			$config = array();
		}
		
		$controllerKeyword = (isset($config["controllerKeyword"]))?$config["controllerKeyword"]:self::$controllerKeyword;
		$actionKeyword = (isset($config["actionKeyword"]))?$config["actionKeyword"]:self::$actionKeyword;
		if (is_null($controllerName)) {
			$controllerName = $this->in->get($actionKeyword);
		}
		if (is_null($actionName)) {
			$actionName = $this->in->get($actionKeyword);
		}
		if (is_null($controllerName)) {
			throw  new IException("cannot quick run empty controller");
		}
		
		
		//调用控制器
		$controllerClass = IConfig::getControllerClass($controllerName);
		if (is_null($controllerClass)) {
			$pieces = explode(".", $controllerName);
			$controllerClassName = array_pop($pieces);
			if (empty($pieces)) {
				$controllerClass = ucfirst($controllerClassName) . "Controller";
			}
			else {
				$controllerClass = implode(".", $pieces) . "." . ucfirst($controllerClassName) . "Controller";
			}
		}
		
		$controller = IObjectFactory::getSingleObject($controllerClass);
		if (is_null($controller)) {
			throw new IException("cannot find class '{$controllerClass}' for '{$controllerName}' controller");
		}
		$controller->setAction($actionName);
		$controller->run();
	}
	
	/**
	 * 加载配置文件.
	 * 
	 * 如果定义了init-file，则加载此文件。
	 * 
	 * 从0.1开始，init-file中可以定义$_CONFIG选项。
	 * <code>
	 * $_CONFIG["host"] = "192.168.0.1";
	 * </code>
	 * 然后在其他地方使用
	 * <code>
	 * echo IConfig.getOptionValue("host");
	 * </code>
	 * 获取该选项的值
	 * 
	 * @param string $configXml 配置文件路径
	 */
	public static function loadConfig($configFile) {
		global $_CONFIG;//使Initialize.php中的选项变为global
		
		if (!is_file($configFile)) {
			//加载默认的配置
			$config = IConfig::load(IFRAMEWORK_DIRECTORY . "/config/application.conf.php");
			define("IFRAMEWORK_CONFIG_DIRECTORY", IF_CONFIG_PATH);
			define("IFRAMEWORK_APP_ROOT", realpath(dirname(IF_CONFIG_PATH)));
		}
		else {
			$config = IConfig::load(realpath($configFile));
			define("IFRAMEWORK_CONFIG_DIRECTORY", realpath(dirname($configFile)));
			
			//定义App-Root
			if (!isset($config["app-root"])) {
				throw new Exception("can't find app-root option in config file '{$configFile}'");
			}
			$appRoot = $config["app-root"];
			if (!native::isAbsolutePath($appRoot)) {
				$appRoot = IFRAMEWORK_CONFIG_DIRECTORY . "/" . $appRoot;
			}
			define("IFRAMEWORK_APP_ROOT", realpath($appRoot));
		}

		//include path
		if (isset($config["include-path"]) && is_array($config["include-path"])) {
			foreach ($config["include-path"] as $key=>$path) {
				if (!native::isAbsolutePath($path)) {
					$config["include-path"][$key] = IFRAMEWORK_APP_ROOT . "/" . $path;
				}
			}
			set_include_path(get_include_path() . PATH_SEPARATOR . implode(PATH_SEPARATOR, $config["include-path"]));
		}
		
		//错误报告级别
		if (!is_null(IConfig::getErrorReportingLevel())) {
			error_reporting(IConfig::getErrorReportingLevel());
		} 
		
		//初始化
		$initFile = IConfig::getOptionValue("init-file");
		if ($initFile != null) {
			$initFileObject = self::getRelativeFile($initFile);
			if (!$initFileObject->exists() || !$initFileObject->isFile()) {
				ILogger::warning("can't find initialize file '{$initFile}'");
			}
			else {
				require_once($initFileObject->getPath());
			}
		}
	}
	
	/**
	 * 加载MVC配置
	 *
	 * @param string $mvcConfigFile MVC配置文件
	 * @since 0.0.3
	 */
	public static function loadMvcConfig($mvcConfigFile) {
		$mvcFile = self::getRelativeFile($mvcConfigFile);
		
		//加载默认配置
		$mvcConfig = IConfig::loadMvc(IFRAMEWORK_DIRECTORY . "/config/mvc.conf.php");
		if ($mvcFile->exists()) {
			$mvcConfig2 = IConfig::loadMvc($mvcFile->getAbsolutePath());
			$mvcConfig = array_merge($mvcConfig, $mvcConfig2);
		}
		
		//报头
		if (isset($mvcConfig["controller"]["headers"]) && !headers_sent()) {
			$headers = $mvcConfig["controller"]["headers"];
			if (is_array($headers)) {
				foreach ($headers as $type=>$content) {
					header($type . ":" . $content);
				}
			}
		}
		
		//加载mint
		if (isset($mvcConfig["mint"])) {
			IMint::setOptions($mvcConfig["mint"]);
		}
		
		//加载dar
		self::loadDar();
	}
	
	/**
	 * 加载dar(Database Active Record)
	 *
	 * @since 0.1
	 */
	public static function loadDar() {
		$mvcConfig = IConfig::getMvcConfig();
		if (isset($mvcConfig["dar"]) && is_array($mvcConfig["dar"])) {
			IDarModelFactory::getInstance()->load($mvcConfig["dar"]);
		}
	}
	
 	/**
	 * 从文件路径中取得相对于IApplication类的文件对象(IFile)
	 *
	 * @param string $path 文件路径
	 * @return IFile
	 */
	public static function getRelativeFile($path) {
		if (IFile::isAbsolutePath($path)) {
			return new IFile($path);
		}
		if (is_file($path)) {
			return new IFile($path);
		}
		else {
			return new IFile(IFRAMEWORK_APP_ROOT . "/" . $path);
		}
	}
	
	/**
	 * 调用未定义属性时激活的方法
	 * 
	 * 不允许子类覆写此方法
	 *
	 * @param string $varname 调用的属性名
	 * @return mixed
	 */
	public final function __get($varname) {
		try {
			return IReflection::getProperty($this, $varname);
		}
		catch (IException $e) {
			return $this->$varname = new IEmptyObject();
		}
	}
	
	/**
	 * 取得当前执行的action
	 *
	 * @return string
	 */
	public function getAction() {
		return $this->action;	
	}
	
	/**
	 * 跳转到新的URL
	 *
	 * @param string $url URL
	 */
	public function goto($url) {
		IResponse::sendRedirect($url);
	}
	
	/**
	 * 取得框架的版本
	 *
	 * @return string
	 * @since 0.0.1
	 */
	public function getVersion() {
		return "I-Framework v0.2.1";
	}
	
	/**
	 * 添加过滤器
	 *
	 * @param IFilter $filter 过滤器
	 * @since 0.0.3
	 */
	public function addFilter(IFilter $filter) {
		if ($this->filterChain == null) {
			$this->filterChain = new IFilterChain($this);
		}
		$this->filterChain->addFilter($filter);
	}
	
	/**
	 * 添加一组过滤器
	 *
	 * @param IFilter $filter
	 * @since 0.0.3
	 */
	public function addFilters($filterArray) {
		if ($this->filterChain == null) {
			$this->filterChain = new IFilterChain($this);
		}
		foreach ($filterArray as $filter) {
			$this->filterChain->addFilter($filter);
		}
	}
	
	/**
	 * 取得客户端输入
	 * 
	 * 通过该方法，你可以
	 * - 在其他类中，比如过滤器，得到客户端输入
	 * - 不经过浏览器，直接给in对象加入值，可以不经过Web Server就可以测试Controller
	 *
	 * @return in
	 * @since 0.0.3
	 */
	public function &getIn() {
		return $this->in;
	}
	
	/**
	 * 设置客户端输入
	 *
	 * @param in &$in in对象
	 * @since 0.0.3
	 */
	public function setIn(in &$in) {
		$this->in = &$in;
	}
	
	/**
	 * 取得filter链
	 *
	 * @return IFilterChain
	 * @since 0.0.3
	 */
	public function &getFilterChain() {
		return $this->filterChain;
	}
	
	/**
	 * 显示mint模板
	 * 
	 * 在action中使用
	 * <code>
	 * $this->display("index");
	 * </code>
	 * 相当于
	 * <code>
	 * return new IModelAndTemplate($this, "index");
	 * </code>
	 * 
	 * 从0.1开始，可以在模板中使用app和in变量，比如
	 * <pre>
	 * {$app.params[controller]}
	 * {$app.path}
	 * {$in.id}
	 * ...
	 * </pre>
	 *
	 * @param mixed $template 模板名或模板对象
	 * @param string $format 格式
	 * @since 0.0.3
	 */
	public function display($template, $format = null) {
		if ($format == null) {
			$format = IMintConfig::HTML_FORMAT;
		}
		$modelAndTemplate = new IModelAndTemplate($this, $template, $format);
		$modelAndTemplate->put("in", $this->getIn());
		$modelAndTemplate->put("app", $this);
		$modelAndTemplate->invoke();
	}
	
	/**
	 * 当请求方法为POST时调用$action_Post方法
	 *
	 * 当$action_Post方法的返回值为false时，终止程序
	 * 
	 * @return boolean 
	 * @since 0.0.3
	 */
	public function callPost() {
		if ($this->in->isPost()) {
			$postMethod = self::$actionPrefix . $this->action . "_Post";
			if (method_exists($this, $postMethod)) {
				if ($this->$postMethod() === false) {
					exit();
				}
			}
		}
	}
	
	/**
	 * 跳转到新的action上
	 *
	 * @param string $controllerOrActionName 控制器或者action名称
	 * @param string $actionName action名称
	 * @since 0.0.3
	 */
	public function redirect($controllerOrActionName, $actionName = null, array $params = null) {
		$path = $this->getPath($controllerOrActionName, $actionName);
		if (is_array($params)) {
			$query = array();
			foreach ($params as $key=>$value) {
				$query[] = $key . "=" . urlencode($value);
			}
			if (!empty($params)) {
				$path .= "?" . implode("&", $query);
			}
		}
		$this->goto($path);
	}
	
	/**
	 * 在当前界面绘制新的action
	 * 
	 * 支持:
	 * - forward(action)
	 * - forward(controller, action)
	 *
	 * @param string $controllerOrActionName 控制器或者action名称
	 * @param string $actionName action名称
	 * @since 0.1
	 */
	public function forward($controllerOrActionName, $actionName = null, array $params = null) {
		if (is_null($controllerOrActionName) && is_null($actionName)) {
			return;
		}
		if (is_null($actionName)) {
			$controllerName = $this->controller;
			$actionName = $controllerOrActionName;
		}
		else {
			$controllerName = $controllerOrActionName;
		}
	
		$path = $this->getPath($controllerName, $actionName, true);
		$route = new IRoute(new IURI($path));
		$controller = $route->getController();
		if (!empty($params)) {
			foreach ($params as $key=>$value) {
				$controller->addParam($key, $value);
			}
		}
		$controller->run();
	}
	
	/**
	 * 取得当前路径
	 * 
	 * - 如果$controllerOrActionName为null,则为当前控制器
	 * - 如果$actionName为null,则控制器为当前控制器，action为$controllerOrActionName
	 *
	 * @param string $controllerOrActionName 控制器或者action名称
	 * @param string $actionName action名称
	 * @param boolean $full 是否为完整的路径
	 * @since 0.0.3
	 */
	public function getPath($controllerOrActionName = null, $actionName = null, $full = false) {
		if (is_null($controllerOrActionName)) {
			$controllerOrActionName = $this->controller;
			if (is_null($actionName)) {
				$actionName = $this->action;
			}
		}
		$routeConfig = IConfig::getRouteConfig();
		if (isset($routeConfig["standard"]["path"])) {
			if (is_null($actionName)) {
				$controllerName = $this->controller;
				$actionName = $controllerOrActionName;
			}
			else {
				$controllerName = $controllerOrActionName;				
			}
			$controllerName = str_replace(".", "/", $controllerName);
			$path = str_replace(array("%{controller}", "%{action}"), array($controllerName, $actionName), $routeConfig["standard"]["path"]);
			
			if (!$full && isset($routeConfig["standard"]["alias"])) {//用来简化链接
				$alias = $routeConfig["standard"]["alias"];
				if (is_array($alias)) {
					foreach ($alias as $left=>$right) {
						$left = str_replace(array("%{controller}", "%{action}"), array($controllerName, $actionName), $left);				
						if ($left == $path) {
							$path = str_replace(array("%{controller}", "%{action}"), array($controllerName, $actionName), $right);
						}
					}
				}
			}
//			$path = str_replace(".", "/", $path);
			return $path;
		}
		throw new IException("can't find route config for standard path");
	}
	
	/**
	 * 设置controller
	 *
	 * @param string $name controller名称
	 * @since 0.0.3
	 */
	public function setController($name) {
		$this->controller = $name;
	}
	
	/**
	 * 取得controller名称
	 *
	 * @return string
	 * @since 0.0.3
	 */
	public function getController() {
		return $this->controller;
	}
	
	/**
	 * 从URI的查询字符串中获取controller名称
	 *
	 * @return string
	 * @since 0.0.3
	 */
	public static function getControllerFromQuery() {
		$in = in::getInstance();
		return $in->get(self::$controllerKeyword);
	}
	
	/**
	 * 从URI的查询字符串中获取action名称
	 *
	 * @return string
	 * @since 0.0.3
	 */
	public static function getActionFromQuery() {
		$in = in::getInstance();
		return $in->get(self::$actionKeyword);
	}
	
	/**
	 * 取得参数值
	 * 
	 * 该参数为当前控制器所有的附加属性，多数用于存储和控制器相关的参数
	 * 
	 * 在mvc.conf.php中的patterns中的选项中的每个值（controller、action、...）都可以通过此函数获得
	 *
	 * @param mixed $name 参数名
	 * @return mixed
	 * @since 0.1
	 */
	public function getParam($name) {
		if (array_key_exists($name, $this->params)) {
			return $this->params[$name];
		}
		return null;
	}
	
	/**
	 * 添加参数
	 *
	 * @param mixed $name 参数名，一般为字符串
	 * @param mixed $value 参数值
	 * @since 0.1
	 */
	public function addParam($name, $value) {
		$this->params[$name] = $value;
		in::getInstance()->set($name, $value);
	}
	
	/**
	 * 取得所有参数
	 *
	 * @return array
	 * @since 0.1
	 */
	public function getParams() {
		return $this->params;
	}
	
	/**
	 * 取得action的返回值
	 *
	 * @return mixed
	 * @since 0.1.1
	 */
	public function getActionReturn() {
		return $this->actionReturn;
	}
	
	/**
	 * 取得DAR驱动
	 *
	 * @return IDarProvider
	 * @since 0.2
	 */
	public function getDarProvider() {
		return IDarModelFactory::getInstance()->getProvider();
	}
	
	/**
	 * 加载用户配置
	 * 
	 * 将config/user.conf.php中的配置加载到系统中
	 *
	 * @since 0.2.1
	 */
	public static function loadUserConfig($configFile) {
		global $config,$_CONFIG;
		if (!is_array($_CONFIG)) {
			$_CONFIG = array();
		}
		if (is_file($configFile)) {
			require(realpath($configFile));
			if (is_array($config)) {
				$_CONFIG = array_merge($_CONFIG, $config);
			}
		}
	}
	
	/**
	 * 初始化
	 *
	 * @since 0.2.1
	 */
	public static function initialize() {
		//检测环境
		if (version_compare(phpversion(), "5.1.3") < 0) {
			throw new IException("PHP version >= 5.1.3 is required, please upgrade your enviroment (from PHP " . phpversion() . ")");	
		}
		
		//加载配置
		IApplication::loadConfig(IF_CONFIG_PATH . "/application.conf.php");
		IApplication::loadMvcConfig(IF_CONFIG_PATH . "/mvc.conf.php");
		IApplication::loadUserConfig(IF_CONFIG_PATH . "/user.conf.php");
	}
	
	/**
	 * 启动I-F
	 *
	 * @since 0.2.1
	 */
	public static function startup() {
		$uri = new IURI(IServer::getRequestUri());
		$route = new IRoute($uri);
		$route->run();
	}
	
	/**
	 * 尝试从路径中得到控制器
	 *
	 * 尝试把 /a/b/c/d 转换为 a.b.c/d，返回
	 *    array(
	 * 			"controller" => "a.b.c",
	 * 			"action" => "d"
	 *    )
	 * 
	 * 这时的index动作不能简写
	 * 
	 * @param string $baseUrl 基本路径
	 * @param string $path 控制器路径
	 * @return array
	 * @since 0.2.1
	 */
	public static function getControllerFromPath($baseUrl, $path) {
		$baseUrl = rtrim($baseUrl, "/");
		$realUrl = trim($path, "/");
		if ($realUrl == "") {
			define("__ROUTE__", $baseUrl);
			return array("controller" => "index", "action" => self::$defaultAction);
		}
		
		//分解控制器和动作
		$pieces = explode("/", $realUrl);
		if (count($pieces) == 1) {
			//设置路径
			IConfig::setKeysValue(IConfig::getMvcConfig(), "route.standard", array(
				"path" => $baseUrl . "/%{controller}/%{action}",
			));
			define("__ROUTE__", $baseUrl);
			return array("controller" => $pieces[0], "action" => self::$defaultAction);
		}
		$last = array_pop($pieces);
		if (preg_match("/^\d+$/", $last)) {
			in::getInstance()->set("id", $last);
			$action = array_pop($pieces);
		}
		else {
			$action = $last;
		}
		
		
		//设置路径
		IConfig::setKeysValue(IConfig::getMvcConfig(), "route.standard", array(
			"path" => $baseUrl . "/%{controller}/%{action}",
		));
		define("__ROUTE__", $baseUrl);
		return array("controller" => implode(".", $pieces), "action" => $action);
	}
}


?>